package cn.stylefeng.guns.modular.business.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.config.redis.redis.Redis0Template;
import cn.stylefeng.guns.config.redis.redis.util.Redishandler0;
import cn.stylefeng.guns.core.*;
import cn.stylefeng.guns.modular.business.entity.MoneyLog;
import cn.stylefeng.guns.modular.business.entity.UserGrade;
import cn.stylefeng.guns.modular.business.entity.UserProperty;
import cn.stylefeng.guns.modular.business.entity.UserTransactionLog;
import cn.stylefeng.guns.modular.business.mapper.UserGradeMapper;
import cn.stylefeng.guns.modular.business.model.RedisINCRDTO;
import cn.stylefeng.guns.modular.business.model.dto.UserGradeDTO;
import cn.stylefeng.guns.modular.business.model.params.MessageDTO;
import cn.stylefeng.guns.modular.business.model.params.MessageType;
import cn.stylefeng.guns.modular.business.model.params.UserGradeParam;
import cn.stylefeng.guns.modular.business.model.params.WxMessageDTO;
import cn.stylefeng.guns.modular.business.model.result.UserGradeDetailResult;
import cn.stylefeng.guns.modular.business.model.result.UserGradeResult;
import cn.stylefeng.guns.modular.business.service.*;
import cn.stylefeng.guns.sys.core.exception.enums.BizExceptionEnum;
import cn.stylefeng.guns.sys.core.util.DateUtil;
import cn.stylefeng.guns.sys.core.util.StringUtils;
import cn.stylefeng.guns.sys.modular.system.entity.User;
import cn.stylefeng.guns.sys.modular.system.service.UserService;
import cn.stylefeng.roses.core.util.ToolUtil;
import cn.stylefeng.roses.kernel.model.exception.ServiceException;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections4.list.TreeList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户等级表 服务实现类
 * </p>
 *
 * @author jwj
 * @since 2019-07-18
 */
@Service
public class UserGradeServiceImpl extends ServiceImpl<UserGradeMapper, UserGrade> implements UserGradeService {


    @Autowired
    private Redis0Template redis0Template;
    @Autowired
    private Redishandler0 redishandler0;

    @Value("${file.downUrl}")
    private String fileDownUrl;

    @Autowired
    private UserPropertyService userPropertyService;

    @Autowired
    private CardService cardService;

    @Autowired
    private UserService userService;

    @Autowired
    private MoneyLogService moneyLogService;

    @Autowired
    private UserTransactionLogService userTransactionLogService;

    @Autowired
    private MessageNoticeService messageNoticeService;

    @Autowired
    private MessageService messageService;



    @Override
    public void add(UserGradeParam param) {
        UserGrade entity = getEntity(param);
        this.save(entity);
        //缓存
        redishandler0.cacheHash(RecoverConst.USER_GRADE_REDIS_KEY, "", param.getLevel() + "", JSONObject.toJSONString(entity));
    }

    @Override
    public void delete(UserGradeParam param) {
        UserGrade userGrade = new UserGrade();
        userGrade.setGradeId(param.getGradeId());
        userGrade.setDeleteFlag(RecoverConst.DEL_FLAG_TRUE);
        this.updateById(userGrade);
        //缓存
        redishandler0.removeHash(RecoverConst.USER_GRADE_REDIS_KEY, "", param.getLevel() + "");
    }

    @Override
    public void update(UserGradeParam param) {
//        UserGrade oldEntity = getOldEntity(param);
        UserGrade newEntity = new UserGrade();
        ToolUtil.copyProperties(param, newEntity);
        this.updateById(newEntity);
        redishandler0.cacheHash(RecoverConst.USER_GRADE_REDIS_KEY, "", param.getLevel() + "", JSONObject.toJSONString(newEntity));

    }

    @Override
    public UserGradeResult findBySpec(UserGradeParam param) {
        return null;
    }

    @Override
    public List<UserGradeResult> findListBySpec(UserGradeParam param) {
        return null;
    }

    @Override
    public LayuiPageInfo findPageBySpec(UserGradeParam param) {
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageList(pageContext, param);
        return LayuiPageFactory.createPageInfo(page);
    }

    private Serializable getKey(UserGradeParam param) {
        return param.getGradeId();
    }

    private Page getPageContext() {
        return LayuiPageFactory.defaultPage();
    }

    private UserGrade getOldEntity(UserGradeParam param) {
        return this.getById(getKey(param));
    }

    private UserGrade getEntity(UserGradeParam param) {
        UserGrade entity = new UserGrade();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }

    /**
     * 获取等级明细
     *
     * @return
     */
    @Override
    public UserGradeDetailResult detail(Long userId) {
        UserGradeDetailResult userGradeDetailResult = new UserGradeDetailResult();
        //获取用户等级
        UserProperty userProperty = Optional.ofNullable(userPropertyService.getPropertyByUserId(userId)).orElseThrow(() -> new ServiceException(400, "用户等级不存在"));
        userGradeDetailResult.setGradeLevel(userProperty.getGradeLevel());
        //从缓存中获取用户等级
        Map<Object, Object> gradeMap = redishandler0.getHashMap(RecoverConst.USER_GRADE_REDIS_KEY, "");
        List<UserGradeDTO> userGradeDTOs = new TreeList<>();
        gradeMap.forEach((k, v) -> {
            UserGradeDTO userGradeDTO = new UserGradeDTO();
            UserGrade grade = JSONObject.parseObject(v.toString(), UserGrade.class);
            userGradeDTO.setLevel(grade.getLevel());
            if (grade.getLevel().equals(UserGradeLevel.first_level.getCode())) {
                userGradeDetailResult.setFirstMoney(grade.getFee().multiply(grade.getUpRate1()));
            } else {
                userGradeDetailResult.setSecondMoney(grade.getFee().multiply(grade.getUpRate1()));
                userGradeDetailResult.setFee(grade.getFee());
            }
            if (grade.getLevel().equals(userProperty.getGradeLevel())) {
                userGradeDetailResult.setGradeName(grade.getGradeName());
            }
            userGradeDTO.setGradeName(grade.getGradeName());
            userGradeDTO.setUpScore(grade.getUpScore());
            userGradeDTO.setIcon(grade.getIcon());
            //计算百分比
            userGradeDTO.setAddRate(convertPercent(grade.getDecrRate()));
            userGradeDTO.setPayRate1(convertPercent(grade.getDecrRate()));
            userGradeDTO.setPayRate2(convertPercent(grade.getDecrRate()));
            //userGradeDTO.setPayRate3(convertPercent(grade.getPayRate3()));
            userGradeDTO.setUpRate1(convertPercent(grade.getUpRate1()));
            userGradeDTO.setUpRate2(convertPercent(grade.getUpRate2()));
            //userGradeDTO.setUpRate3(convertPercent(grade.getUpRate3()));
            userGradeDTO.setFee(grade.getFee());
            userGradeDTOs.add(userGradeDTO);
        });
        CollectionUtil.sortByProperty(userGradeDTOs, "level");
        userGradeDetailResult.setGradeDTOList(userGradeDTOs);
        return userGradeDetailResult;
    }

    /**
     * 转换百分比
     *
     * @param num1
     * @return
     */
    public String convertPercent(BigDecimal num1) {
        NumberFormat format = NumberFormat.getPercentInstance();
        format.setMaximumFractionDigits(2);//设置保留几位小数
        return format.format(num1);
    }

    /**
     * 获取等级信息
     *
     * @param level
     * @return
     */
    @Override
    public UserGrade getUserGradeByLevel(Integer level) {
        return this.getOne(new QueryWrapper<UserGrade>().eq("delete_flag", RecoverConst.DEL_FLAG_FALSE).eq("level", level));
    }

    /**
     * 升级用户等级
     *
     * @param userId     用户id
     * @param orderNo    订单号
     * @param gradeLevel 等级 2：中级，3：高级
     * @param money      金额
     * @param payMode    交易方式：0：支付宝，1：微信，2：银行卡,3:余额
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(Long userId, String orderNo, String gradeLevel, BigDecimal money, Integer payMode) {
        User user = Optional.ofNullable(userService.getById(userId)).orElseThrow(() -> new ServiceException(BizExceptionEnum.NO_THIS_USER));
        //记录交易流水
        UserTransactionLog userTransactionLog = new UserTransactionLog();
        if (payMode.equals(PayModeType.AMOUNT.getCode())) {
            BigDecimal totalAmount = moneyLogService.totalAmount(userId);
            if (totalAmount != null && user.getAmount().compareTo(totalAmount) != 0) {
                BigDecimal diffMoney = totalAmount.subtract(user.getAmount());
                MoneyLog moneyLog = new MoneyLog();
                moneyLog.setType(MoneyLogType.SYS_CORRECT.getCode());
                if (user.getAmount().compareTo(totalAmount) > 0) {
                    moneyLog.setRemark("系统冲正，给您增加了" + diffMoney.floatValue()+ "元");
                    moneyLog.setSecondType(1);
                } else {
                    moneyLog.setRemark("系统冲正，减去了您" + diffMoney.floatValue()+ "元");
                    moneyLog.setSecondType(2);
                }
                moneyLog.setNewAmount(user.getAmount().add(diffMoney));
                moneyLog.setOldAmount(user.getAmount());
                moneyLog.setUserId(user.getUserId());
                moneyLog.setAmount(diffMoney);
                moneyLogService.save(moneyLog);
                user.setAmount(totalAmount);
                userService.update(new UpdateWrapper<User>().setSql("amount=amount+" + diffMoney.floatValue()).eq("user_id", user.getUserId()));
                redishandler0.cacheStringValue(RecoverConst.MONEY_USER_AMOUNT, user.getUserId().toString(), user.getAmount().add(diffMoney).multiply(new BigDecimal(1000)).longValue() + "");
            }
            if (user.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
                throw new ServiceException(500, "用户没有可用余额");
            }
            if (money.compareTo(user.getAmount()) > 0) {
                throw new ServiceException(BizExceptionEnum.NOT_SUFFICIENT_FUNDS);
            }
            UserProperty userProperty = userPropertyService.getById(userId);
            if (userProperty.getGradeLevel().equals(UserGradeLevel.second_level.getCode())) {
                throw new ServiceException(506, "已经是VIP，无需升级");
            }
            userService.update(new UpdateWrapper<User>().setSql("amount=amount-" + money).eq("user_id", userId));
            String gradeStr = redishandler0.getHash(RecoverConst.USER_GRADE_REDIS_KEY, "",  gradeLevel);
            UserGrade userGrade = null;
            if (StringUtils.isNotEmpty(gradeStr)) {
                userGrade = JSONObject.parseObject(gradeStr, UserGrade.class);
            }
            /*user.setUpdateTime(new Date());
            user.setAmount(user.getAmount().subtract(money).setScale(2,BigDecimal.ROUND_HALF_UP));
            userService.updateById(user);*/
            //记录金额流水
            MoneyLog moneyLog = new MoneyLog();
            moneyLog.setUserId(userId);
            moneyLog.setType(MoneyLogType.BUY_GRADE.getCode());
            moneyLog.setAmount(money.negate());
            Long oldAmount = redishandler0.incr(RecoverConst.MONEY_USER_AMOUNT, userId.toString(), 0);
            BigDecimal oldAmo = new BigDecimal("" + oldAmount).divide(new BigDecimal("" + 1000));
            moneyLog.setOldAmount(oldAmo);
            moneyLog.setNewAmount(oldAmo.add(money.negate()));
            moneyLog.setBusinessId(userTransactionLog.getOrderId());
            moneyLog.setBusinessNO(orderNo);

            userTransactionLog.setPayMode(PayModeType.AMOUNT.getCode());
            userTransactionLog.setOrderNo(orderNo);
            userTransactionLog.setUserId(userId);
            userTransactionLog.setAmount(money);
            userTransactionLog.setState(2);
            userTransactionLog.setType(1);
            userTransactionLog.setToLevel(Integer.valueOf(gradeLevel));
            userTransactionLogService.save(userTransactionLog);
            moneyLog.setRemark("您升级的" + userGrade.getGradeName() + "会员已经成功");
            moneyLog.setBusinessId(userTransactionLog.getOrderId());
            moneyLog.setBusinessNO(userTransactionLog.getOrderNo());
            moneyLogService.save(moneyLog);
            //处理推荐利润
            List<RedisINCRDTO> list = saveProfile(money, userId);
            if (list == null) {
                redishandler0.incr(RecoverConst.MONEY_USER_AMOUNT, userTransactionLog.getUserId().toString(), money.negate().multiply(new BigDecimal(1000)).longValue());
            } else {
                RedisINCRDTO userIncr = new RedisINCRDTO(RecoverConst.MONEY_USER_AMOUNT, userTransactionLog.getUserId().toString(), money.negate().multiply(new BigDecimal(1000)).longValue());
                list.add(userIncr);
                if(list != null) {
                    //更新缓存放在最后，回滚的话，可以不用操作缓存
                    List<Object> redisResult = redis0Template.executePipelined(new RedisCallback<Object>() {
                        @Override
                        public String doInRedis(RedisConnection connection) throws DataAccessException {
                            for (RedisINCRDTO redisINCRDTO : list) {
                                connection.incrBy((redisINCRDTO.getRedisPreKey() + redisINCRDTO.getRedisKey()).getBytes(), redisINCRDTO.getValue());
                            }
                            return null;
                        }
                    });
                }
            }
            userProperty.setUserId(userId);
            userProperty.setGradeLevel(Integer.valueOf(gradeLevel));
            userProperty.setGradeId(userGrade.getGradeId());
            userProperty.setRelationPath(userProperty.getRelationPath().split("-")[0]);
            userProperty.setRecommendLevel(RecoverConst.USER_GRADE_LEVEL_FIRST);
            userProperty.setParentId(Long.valueOf(userProperty.getRelationPath().split("-")[0]));
            userProperty.setParentGradeId(userGrade.getGradeId());
            userProperty.setParentLevel(userGrade.getLevel());
            userPropertyService.updateById(userProperty);
            messageNoticeService.add("升级成功通知", "你好，恭喜你成功升级VIP黄金会员，感谢您的使用", MessageNoticeType.system.getCode(), userId);
            sendSuccessMessageToUser(user.getOpenid());
            return true;
        } else {
            userTransactionLog.setOrderNo(orderNo);
            userTransactionLog.setUserId(userId);
            userTransactionLog.setAmount(money);
            userTransactionLog.setState(1);
            userTransactionLog.setType(1);
            userTransactionLog.setPayMode(payMode);
            userTransactionLog.setToLevel(Integer.valueOf(gradeLevel));
            return userTransactionLogService.save(userTransactionLog);
        }
    }

    /**
     * 发送升级通知
     * @param openId
     */
    private void sendSuccessMessageToUser(String openId) {
        MessageDTO messageDTO = new MessageDTO();
        messageDTO.setUserIdList(Collections.singletonList(openId));
        messageDTO.setMessageType(MessageType.UP_GRADE);
        WxMessageDTO wxMessageDTO = new WxMessageDTO();
        wxMessageDTO.setFirst("您好，您已成功升级为VIP黄金会员");
        wxMessageDTO.setKeyword1("VIP黄金会员");
        wxMessageDTO.setKeyword2("永久有效");
        wxMessageDTO.setRemark("升级之后，您将获得更多的优惠机会。");
        messageDTO.setData(wxMessageDTO);
        messageService.sendTemplateMessage(messageDTO);
    }

    /**
     * 支付回调之后的业务处理
     *
     * @param params
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean toUpGrade(Map<String, String> params, Integer type) {
        String outTradeNo = params.get("out_trade_no");
        String tradeNo = params.get("trade_no");
        BigDecimal money = new BigDecimal(params.get("total_amount"));
        UserTransactionLog userTransactionLog =  userTransactionLogService.getOne(new QueryWrapper<UserTransactionLog>().eq("order_no", outTradeNo));
        //如果已经回调过，那么直接返回成功
        if (userTransactionLog.getState().equals(2)) {
            return true;
        }
        String gradeStr = redishandler0.getHash(RecoverConst.USER_GRADE_REDIS_KEY, "",  userTransactionLog.getToLevel().toString());
        UserGrade userGrade = null;
        if (StringUtils.isNotEmpty(gradeStr)) {
            userGrade = JSONObject.parseObject(gradeStr, UserGrade.class);
        }
        UserProperty userProperty =  userPropertyService.getById(userTransactionLog.getUserId());

        //userService.update(new UpdateWrapper<User>().setSql("amount=amount-" + money).eq("user_id", userTransactionLog.getUserId()));
        userTransactionLog.setState(2);
        userTransactionLog.setPayNo(tradeNo);
        userTransactionLog.setPayTime(new Date());
        userTransactionLogService.updateById(userTransactionLog);
        /*
         *记录金额流水
         * 1、先添加充值流水
         * 2、再添加升级流水
         */
        MoneyLog addMoneylog = new MoneyLog();
        addMoneylog.setUserId(userTransactionLog.getUserId());
        //充值
        addMoneylog.setType(6);
        addMoneylog.setSecondType(type);
        Long oldAmount = redishandler0.incr(RecoverConst.MONEY_USER_AMOUNT, userTransactionLog.getUserId().toString(), 0);
        BigDecimal oldAmo = new BigDecimal("" + oldAmount).divide(new BigDecimal("" + 1000));
        addMoneylog.setOldAmount(oldAmo);
        addMoneylog.setNewAmount(oldAmo.add(money));
        addMoneylog.setAmount(money);
        addMoneylog.setCreateTime(new Date());
        addMoneylog.setUpdateTime(new Date());
        if (PayModeType.WECHAT.getCode() == userTransactionLog.getPayMode().intValue()) {
            addMoneylog.setRemark("您从微信支付的" + money.toString() + "已经成功支付，请注意查收");
        } else {
            addMoneylog.setRemark("您从支付宝支付的" + money.toString() + "已经成功支付，请注意查收");
        }

        addMoneylog.setBusinessId(userTransactionLog.getOrderId());
        addMoneylog.setBusinessNO(userTransactionLog.getOrderNo());
        moneyLogService.save(addMoneylog);
        //升级
        MoneyLog subsMoneylog = new MoneyLog();
        subsMoneylog.setUserId(userTransactionLog.getUserId());
        //充值
        addMoneylog.setType(5);
        addMoneylog.setOldAmount(addMoneylog.getNewAmount());
        addMoneylog.setNewAmount(addMoneylog.getNewAmount().subtract(money));
        addMoneylog.setAmount(money.negate());
        addMoneylog.setCreateTime(DateUtil.addMinute(new Date(), 1));
        addMoneylog.setUpdateTime(DateUtil.addMinute(new Date(), 1));
        addMoneylog.setRemark("您购买升级的" + userGrade.getGradeName() + "会员已经成功，请注意查收");
        addMoneylog.setBusinessId(userTransactionLog.getOrderId());
        addMoneylog.setBusinessNO(userTransactionLog.getOrderNo());
        moneyLogService.save(addMoneylog);

        //处理推荐利润
        List<RedisINCRDTO> list = saveProfile(money, userTransactionLog.getUserId());
        if (list == null) {
            /*RedisINCRDTO userIncr = new RedisINCRDTO(RecoverConst.MONEY_USER_AMOUNT, userTransactionLog.getUserId().toString(), money.negate().multiply(new BigDecimal(1000)).longValue());
            redishandler0.incr(userIncr.getRedisPreKey(), userIncr.getRedisKey(), userIncr.getValue());*/
        } else {
            /*RedisINCRDTO userIncr = new RedisINCRDTO(RecoverConst.MONEY_USER_AMOUNT, userTransactionLog.getUserId().toString(), money.negate().multiply(new BigDecimal(1000)).longValue());
            list.add(userIncr);*/
            if(list != null) {
                //更新缓存放在最后，回滚的话，可以不用操作缓存
                List<Object> redisResult = redis0Template.executePipelined(new RedisCallback<Object>() {
                    @Override
                    public String doInRedis(RedisConnection connection) throws DataAccessException {
                        for (RedisINCRDTO redisINCRDTO : list) {
                            connection.incrBy((redisINCRDTO.getRedisPreKey() + redisINCRDTO.getRedisKey()).getBytes(), redisINCRDTO.getValue());
                        }
                        return null;
                    }
                });
            }
        }
        userProperty.setUserId(userTransactionLog.getUserId());
        userProperty.setGradeLevel(userTransactionLog.getToLevel());
        userProperty.setGradeId(userGrade.getGradeId());
        userProperty.setRelationPath(userProperty.getRelationPath().split("-")[0]);
        userProperty.setRecommendLevel(RecoverConst.USER_GRADE_LEVEL_FIRST);
        userProperty.setParentId(Long.valueOf(userProperty.getRelationPath().split("-")[0]));
        userProperty.setParentGradeId(userGrade.getGradeId());
        userProperty.setParentLevel(userGrade.getLevel());
        userPropertyService.updateById(userProperty);
        messageNoticeService.add("升级成功通知", "你好，恭喜你成功升级VIP黄金会员，感谢您的使用", MessageNoticeType.system.getCode(), userTransactionLog.getUserId());
        User user = userService.getById(userTransactionLog.getUserId());
        sendSuccessMessageToUser(user.getOpenid());
        return true;
    }


    /**
     * 1、计算上级利润
     * 2、获取上级余额，
     * 3、添加上级分润记录
     * 4、更新上级余额
     * @param userProperty
     * @param mapParent
     * @param gradeList
     */
    private void addProfile(UserProperty userProperty, Map<Long, UserProperty> mapParent, Map<Object, Object> gradeList, Integer parentLevel, BigDecimal amount, List<RedisINCRDTO> list, Long comeUserId, Integer firstRecommedLevel) {
        if (mapParent.get(userProperty.getParentId()) != null) {
            UserProperty parent = mapParent.get(userProperty.getParentId());
            String gradeStr = String.valueOf(gradeList.get(parent.getGradeLevel().toString()));
            if (cn.stylefeng.guns.sys.core.util.StringUtils.isNotEmpty(gradeStr)) {
                UserGrade grade = JSONObject.parseObject(gradeStr, UserGrade.class);
                Long oldAmount = 0L;
                try {
                    BigDecimal payRate = new BigDecimal(0);
                    //1、如果上级是第一级上级，那么判断上级是否是黄金vip，如果是，那么分成为黄金vip的升级折扣 2、如果不是黄金vip，那第一级分成为普通会员的升级折扣
                    //2、如果上级不是第一级，那么判断是否为黄金vip，如果是，参与分成，分成为规则为第一层上级剩余的
                    if (parentLevel == UserGradeLevel.first_level.getCode()) {
                        payRate = grade.getUpRate1();
                    } else {
                        if (firstRecommedLevel.equals(UserGradeLevel.first_level.getCode())) {
                            if (grade.getLevel().equals(UserGradeLevel.second_level.getCode())) {
                                payRate = grade.getUpRate2();
                            }
                        }
                    }
                    if (payRate != null && payRate.compareTo(BigDecimal.ZERO) > 0) {
                        payRate = payRate.setScale(2, BigDecimal.ROUND_HALF_UP);
                        oldAmount = redishandler0.incr(RecoverConst.MONEY_USER_AMOUNT, parent.getUserId().toString(), 0);
                        BigDecimal oldAmountBig = new BigDecimal(oldAmount).divide(new BigDecimal(1000));
                        BigDecimal profile = amount.multiply(payRate);
                        BigDecimal newAmount = oldAmountBig.add(profile);
                        MoneyLog moneyLog = new MoneyLog();
                        moneyLog.setAmount(profile);
                        moneyLog.setNewAmount(newAmount);
                        moneyLog.setOldAmount(oldAmountBig);
                        String content = "间接";
                        if (parentLevel > 1) {
                            moneyLog.setType(MoneyLogType.CARD_EXTEND_J.getCode());
                            moneyLog.setRemark("您间接推荐的用户userId已经升级会员成功，给您贡献了：" + profile.toString());
                            content = "间接";
                        } else {
                            moneyLog.setType(MoneyLogType.CARD_EXTEND_Z.getCode());
                            moneyLog.setRemark("您直接推荐的用户userId已经升级会员成功，给您贡献了：" + profile.toString());
                            content = "直接";
                        }

                        moneyLog.setSecondType(2);
                        moneyLog.setUserId(parent.getUserId());
                        moneyLog.setComeUserId(comeUserId);
                        //moneyLog.setUserName(parent.get);
                        userService.update(new UpdateWrapper<User>().setSql("amount=amount+" + profile).eq("user_id", parent.getUserId()));
                        moneyLogService.save(moneyLog);
                        messageNoticeService.add("升级推广奖励", "恭喜您，您" + content + "推荐的会员升级VIP，奖励您" + profile.toString(), MessageNoticeType.system.getCode(), parent.getUserId());
                        RedisINCRDTO redisINCRDTO = new RedisINCRDTO(RecoverConst.MONEY_USER_AMOUNT, parent.getUserId().toString(), profile.multiply(new BigDecimal(1000)).longValue());
                        list.add(redisINCRDTO);
                    }
                } catch (Exception e) {
                    throw new RuntimeException("添加用户推广资金变动出错2：" + e.getMessage());
                }
                addProfile(mapParent.get(userProperty.getParentId()), mapParent, gradeList, (parentLevel + 1), amount, list, comeUserId, firstRecommedLevel);
            }
        }
    }

    /**
     * 处理分润
     */
    private List<RedisINCRDTO> saveProfile(BigDecimal sysAmount, Long ownuserId){
        //获取所有的等级
        Map<Object, Object> gradeList = redishandler0.getHashMap(RecoverConst.USER_GRADE_REDIS_KEY, "");
        if (gradeList != null && gradeList.size() > 0) {
            //获取用户的所有上级
            UserProperty userProperty = userPropertyService.getOne(new QueryWrapper<UserProperty>().eq("user_id", ownuserId).eq("delete_flag", RecoverConst.DEL_FLAG_FALSE));
            if (userProperty != null) {
                List<UserProperty> parents = getParents(userProperty);
                if (parents == null || parents.size() == 0) {
                    return null;
                }
                Map<Long, UserProperty> mapParent =  parents.stream().collect(Collectors.toMap(UserProperty::getUserId, Function.identity()));
                List<RedisINCRDTO> list = new ArrayList<>();
                addProfile(userProperty, mapParent, gradeList, 1, sysAmount, list, ownuserId, mapParent.get(userProperty.getParentId()).getGradeLevel());
                return list;
            }
        }
        return null;
    }

    private List<UserProperty> getParents(UserProperty userProperty) {
        List<UserProperty> upList = new ArrayList<>();
        if (StringUtils.isEmpty(userProperty.getRelationPath())) {
            return null;
        }
        String[] parentUserIds = userProperty.getRelationPath().split("-");
        List<String> userListT = Arrays.asList(parentUserIds);
        List<String> userList = new ArrayList<>(userListT);
        //userList.remove(userList.size()  - 1);
        if (userList.size() > 0) {
            upList = userPropertyService.list(new QueryWrapper<UserProperty>().in("user_id", userList).eq("delete_flag", RecoverConst.DEL_FLAG_FALSE));
            return upList;
        }
        return null;
    }
}
